﻿using System;
using System.Collections.Generic;

namespace NMapper
{
    public class MapContext<TDatabase>
        where TDatabase : IDisposable
    {
        private Dictionary<object, object> arguments = new Dictionary<object,object>();
        private Dictionary<Tuple<Type, object>, object> cache = new Dictionary<Tuple<Type, object>, object>();

        public DatabaseAdapter<TDatabase> DbAdapter { get; private set; }
        public event Action AfterTransientInitialization;
        public event Action AfterMapToInput;

        public IMappingContext MappingContext { get; set; }

        public MapContext(IMappingContext mappingContext, DatabaseAdapter<TDatabase> dbAdapter, object arguments)
        {
            DbAdapter = dbAdapter;
            this.MappingContext = mappingContext;
            if (arguments != null)
                foreach (var property in arguments.GetType().GetProperties())
                {
                    var value = property.GetValue(arguments, null);
                    this[property.Name] = value;
                }
        }

        public void OnAfterTransientInitialization()
        {
            if (AfterTransientInitialization != null)
                AfterTransientInitialization();
        }

        public void OnAfterMapToInput()
        {
            if (AfterMapToInput != null)
                AfterMapToInput();
        }

        public object this[object key]
        {
            get
            {
                object value;
                arguments.TryGetValue(key, out value);
                return value;
            }
            set
            {
                arguments[key] = value;                
            }
        }

        public int GetInt(object key)
        {
            var result = this[key];
            if (result == null)
                return 0;
            else
                return (int)result;
        }

        public object GetFromCache(Type type, object key)
        {
            object result;
            cache.TryGetValue(Tuple.Create(type, key), out result);
            return result;
        }

        public void Cache(Type type, object key, object output)
        {
            cache[Tuple.Create(type, key)] = output;
        }
    }
}